package org.web30.nntp.sync;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Xia Zhenyu
 */
public class SyncClient {

    public static final String SYNC_INI = "sync.properites";
    public static final String NNTP_SERVER_NAME = "IntranetNNTPServer";
    public static final String NNTP_SERVER_PORT = "IntranetNNTPServerPort";
    public static final String NNTP_SERVER_USER = "IntranetNNTPServerAuthUser";
    public static final String NNTP_SERVER_PASS = "IntranetNNTPServerAuthPass";
    public static final String HTTP_PROXY = "HTTPProxy";
    public static final String HTTP_PROXY_PORT = "HTTPProxyPort";
    public static final String NNTP_BRIDGE_URL = "NNTPBridge";
    public static final String NNTP_BRIDGE_AUTH_USER = "NNTPBridgeAuthUser";
    public static final String NNTP_BRIDGE_AUTH_PASS = "NNTPBridgePass";
    public static final String NNTP_GROUPS = "newsgroups";
    public static final String SIZE_LIMIT = "size_limit";
    public static final String NO_RETRIVE = "silent";
    public static final String INTERVAL = "interval";
    public static final String SYNCID="syncid";

    private ArrayList SyncTasks = new ArrayList();
    /**
     * Only send out articles to internet, but don't retrive articles from internet
     */
    private boolean silentMode = true;
    /**
     * Size limit of article be synced.
     */
    private long sizeLimit = 512 * 1024;
    /**
     * Log File
     */
    private static FileHandler fh = null;
    /**
     * Log handle
     */
    private static Logger logger = Logger.getLogger(SyncClient.class.getName());

    public SyncClient(String config) throws FileNotFoundException, IOException {
        SyncClient.fh = new FileHandler("sync.log");
        logger.addHandler(fh);
        logger.setLevel(Level.ALL);
        this.init(config);
    }

    /**
     * Read properties file
     * @param config file name
     * @throws FileNotFoundException
     * @throws IOException
     */
    private void init(String config) throws FileNotFoundException, IOException {
        String fileName = null;
        if (config == null) {
            fileName = this.getClass().getResource("sync.properties").getPath();
        } else {
            fileName = config;
        }
        Properties profile = new Properties();
        FileInputStream in = new FileInputStream(new File(fileName));
        profile.load(in);
        int sleep = 30000;
        String temp = profile.getProperty(SyncClient.INTERVAL);
        if (temp != null) {
            sleep = Integer.parseInt(temp) * 1000;
        }
        temp = profile.getProperty(SyncClient.SIZE_LIMIT);
        if (temp != null) {
            this.sizeLimit = Integer.parseInt(temp) * 1024;
        }
        temp = profile.getProperty(SyncClient.NO_RETRIVE);
        if (temp != null) {
            if (Integer.parseInt(temp) == 1) {
                this.silentMode = true;
            } else {
                this.silentMode = false;
            }
        }
        int proxyPort = 0;
        temp = profile.getProperty(SyncClient.HTTP_PROXY_PORT);
        if(temp != null) {
            proxyPort = Integer.parseInt(temp);
        }
        String proxy = null;
        proxy = profile.getProperty(SyncClient.HTTP_PROXY);
        
        StringTokenizer tokens = new StringTokenizer((String) profile.get(SyncClient.NNTP_GROUPS), ";");
        String groupName = null;
        while (tokens.hasMoreTokens()) {
            groupName = tokens.nextToken();
            this.createSyncTasks(
                    proxy,
                    proxyPort,
                    profile.getProperty(SyncClient.NNTP_BRIDGE_AUTH_USER),
                    profile.getProperty(SyncClient.NNTP_BRIDGE_AUTH_PASS),
                    profile.getProperty(SyncClient.NNTP_SERVER_NAME),
                    Integer.parseInt(profile.getProperty(SyncClient.NNTP_SERVER_PORT)),
                    profile.getProperty(SyncClient.NNTP_BRIDGE_URL),
                    groupName,
                    sleep);
        }
    }

    /**
     * creat tasks for sync
     * @param httpProxy
     * @param httpProxyPort
     * @param user
     * @param pwd
     * @param intranetNNTPHostName
     * @param intranetNNTPPort
     * @param NNTPBridgeURL
     * @param group
     * @param interval
     */
    private void createSyncTasks(
            String httpProxy,
            int httpProxyPort,
            String user,
            String pwd,
            String intranetNNTPHostName,
            int intranetNNTPPort,
            String NNTPBridgeURL,
            String group,
            int interval) {
        SyncClientService srv = new SyncClientService(
                httpProxy,
                httpProxyPort,
                user,
                pwd,
                intranetNNTPHostName,
                intranetNNTPPort,
                NNTPBridgeURL,
                group,
                interval);
        srv.setSilentMode(silentMode);
        srv.setArticleSizeLimit(sizeLimit);
        this.SyncTasks.add(srv);
        System.out.println("Group: "+group+" added into task");
    }

    /**
     * Start sync thread
     */
    public void startSync() {
        Iterator it = this.SyncTasks.iterator();
        while (it.hasNext()) {
            SyncClientService srv = (SyncClientService) it.next();
            (new Thread(srv)).start();
        }
    }

    public static void main(String[] args) {
        SyncClient clt = null;
        try {
            if (args.length != 0) {
                clt = new SyncClient(args[0]);
            } else {
                clt = new SyncClient(null);

            }
            clt.startSync();
            System.out.println("Sync Process Started");
            while (true) {
                try {
                    Thread.sleep(6000000);
                } catch (InterruptedException ex) {
                    return;
                }
            }

        } catch (FileNotFoundException ex) {
            Logger.getLogger(SyncClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SyncClient.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}
